﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net;
using System.Web;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Twitterizer.Framework;

namespace sqengine.Engine.Common
{

    public class TwitterAPI
    {

        private Game _game;


        #region Thread declare
        private Thread _sendtwitterthread;
        private Thread _updatetwitterpublic;
        private Thread _twittercheckloop;
        private Thread _dmtwitterthread;
        private Thread _replytwitterthread;
        #endregion

        private Twitter _twitter_client;

        private TwitterStatusCollection _publicstatus_list;
        private TwitterStatusCollection _directmessages_list;
        private TwitterStatusCollection _reply_list;


        private int _direct_messagecount = -1;
        private int _reply_messagecount = -1;

        public TwitterAPI(Game game)
        {
            _game = game;

        }


        #region Thread Preparing
        public void PrepareTwitterUpdate(string user, string password, string message)
        {

            _sendtwitterthread = new Thread(delegate()
            {
                SendUpdate(user, password, message);
            });
            _sendtwitterthread.Name = "send twitter thread";
            _sendtwitterthread.Priority = ThreadPriority.Normal;
            _sendtwitterthread.Start();

        }

        public void PrepareTwitterCheckLoop(string user, string password, int update_time, bool active)
        {
            if (active)
            {
                _twittercheckloop = new Thread(delegate()
                    {
                        CheckForTwitterLoop(user, password, update_time, active);
                    });
                _twittercheckloop.Priority = ThreadPriority.Normal;
                _twittercheckloop.Start();
            }
            else
            {
                _twittercheckloop = null;
            }

        }

        public void PrepareTwitterCheckDS(string user, string password)
        {
            _dmtwitterthread = new Thread(delegate()
                {
                    GetDirectMessages(user, password, true);

                });
            _dmtwitterthread.Priority = ThreadPriority.Normal;
            _dmtwitterthread.Start();
        }

        public void PrepareTwitterPTL(string user, string password)
        {
            _updatetwitterpublic = new Thread(delegate()
            {
                GetPublicTimeline(user, password, true);

            });
            _updatetwitterpublic.Priority = ThreadPriority.Normal;
            _updatetwitterpublic.Start();
        }

        public void PrepareTwitterGetReply(string user, string password)
        {
            _replytwitterthread = new Thread(delegate()
            {
                GetReplyMessages(user, password, true);

            });
            _replytwitterthread.Priority = ThreadPriority.Normal;
            _replytwitterthread.Start();
        }

        private string GetProxyInformation()
        {
            bool p_enabled = false;
            bool.TryParse(((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQPROXY_ENABLED), out p_enabled);

            if (p_enabled)
            {

                string url = ((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQPROXY_URL);
                string usern = ((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQPROXY_USER);
                string passwd = ((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQPROXY_PASSWD);

                if (passwd.StartsWith("password:"))
                    passwd = passwd.Replace("password:", " ").TrimStart();

                return string.Format("http://{0}:{1}@{2}/", usern, passwd, url);

            }
            else
            {
                return string.Empty;
            }


        }

        #endregion

        private void InitTwitterClient(string username, string password)
        {
            if (_twitter_client == null)
            {
                _twitter_client = new Twitter(username, password, SqEngine.SqEngineInfo._name, GetProxyInformation());
            }
            else
            {
                _twitter_client.ProxyUri = GetProxyInformation();
            }
        }

        private void SendUpdate(string userName, string password, string data)
        {
            try
            {
                InitTwitterClient(userName, password);
                _twitter_client.Status.Update(data);

                if (_twitter_client.ProxyUri != "")
                {
                    ((sqengine)_game).Console.AddConsole("$4[Twitter]: $0Message sent via proxy");
                }
                else
                {
                    ((sqengine)_game).Console.AddConsole("$4[Twitter]: $0Message sent");
                }
            }
            catch (Exception ex)
            {
                ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: Error! $0{0}", ex.Message));
            }
        }


        private void CheckForTwitterLoop(string username, string password, int update_time, bool active)
        {
            while (active)
            {
                // Get the public timeline, caching the result for two minutes

                InitTwitterClient(username, password);
                _publicstatus_list = GetPublicTimeline(username, password, false);
                _directmessages_list = GetDirectMessages(username, password, false);

                NotifyDirectMessages();
                NotifyReplyMessages();

                Thread.Sleep(update_time);
            }

            if (!active)
                _twittercheckloop = null;


        }

        private TwitterStatusCollection GetDirectMessages(string username, string password, bool output)
        {
            try
            {
                InitTwitterClient(username, password);

                TwitterStatusCollection _directmesgs = _twitter_client.DirectMessages.DirectMessages();

                if (output)
                {
                    foreach (TwitterStatus item in _directmesgs)
                    {
                        ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: DM Date:{0} From: {1} Text: $0{2}", item.Created.Date.ToString(), item.Source, item.Text));
                        Thread.Sleep(100);
                    }

                    if (_dmtwitterthread != null)
                        _dmtwitterthread = null;

                    return null;
                }
                else
                {
                    if (_dmtwitterthread != null)
                        _dmtwitterthread = null;

                    return _directmesgs;

                }


            }
            catch (Exception ex)
            {

                ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: Error! $0{0}", ex.Message));

                if (_dmtwitterthread != null)
                    _dmtwitterthread = null;
                return null;
            }


        }

        private TwitterStatusCollection GetPublicTimeline(string username, string password, bool output)
        {
            try
            {
                InitTwitterClient(username, password);

                TwitterStatusCollection _publictimeline = _twitter_client.Status.PublicTimeline();

                if (output)
                {
                    foreach (TwitterStatus item in _publictimeline)
                    {
                        ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: PTL Date:{0} From: {1} Text: $0{2}", item.Created.Date.ToString(), item.Source, item.Text));
                        Thread.Sleep(100);
                    }

                    if (_updatetwitterpublic != null)
                        _updatetwitterpublic = null;

                    return null;
                }
                else
                {
                    if (_updatetwitterpublic != null)
                        _updatetwitterpublic = null;

                    return _publictimeline;

                }


            }
            catch (Exception ex)
            {

                ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: Error! $0{0}", ex.Message));

                if (_updatetwitterpublic != null)
                    _updatetwitterpublic = null;

                return null;
            }


        }

        private TwitterStatusCollection GetReplyMessages(string username, string password, bool output)
        {
            try
            {
                InitTwitterClient(username, password);

                TwitterStatusCollection _replymessages = _twitter_client.Status.Replies();

                if (output)
                {
                    foreach (TwitterStatus item in _replymessages)
                    {
                        ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: Reply Date:{0} From: {1} Text: $0{2}", item.Created.Date.ToString(), item.Source, item.Text));
                        Thread.Sleep(100);
                    }

                    if (_replytwitterthread != null)
                        _replytwitterthread = null;

                    return null;
                }
                else
                {
                    if (_replytwitterthread != null)
                        _replytwitterthread = null;

                    return _replymessages;

                }


            }
            catch (Exception ex)
            {

                ((sqengine)_game).Console.AddConsole(string.Format("$4[Twitter]: Error! $0{0}", ex.Message));

                if (_dmtwitterthread != null)
                    _dmtwitterthread = null;
                return null;
            }


        }

        private void NotifyDirectMessages()
        {
            bool notify = false;

            bool.TryParse(((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQTWITTER_NOTIFY_DIRECTMESSAGES), out notify);

            if (notify)
            {
                if (_direct_messagecount != -1)
                {

                    if (_directmessages_list.Count > _direct_messagecount)
                    {
                        string from = _directmessages_list[0].TwitterUser.ScreenName;
                        string mesg = _directmessages_list[0].Text;

                        if (((sqengine)_game).IsConsoleActive)
                        {
                            (((sqengine)_game)).Console.AddConsole(string.Format("$4[Twitter]: $0{0}: {1}", from, mesg));
                        }
                        else
                        {
                            (((sqengine)_game)).AddMessage(string.Format("Message from Twitter\n{0}: {1}", from, mesg), Color.Red, 4000, "Textures/UI/twitter-logo");
                        }

                        _direct_messagecount = _directmessages_list.Count;

                    }
                }
                else
                {

                    _direct_messagecount = _directmessages_list.Count;
                }

            }
        }

        private void NotifyReplyMessages()
        {
            bool notify = false;

            bool.TryParse(((sqengine)_game).ConsoleGetVar(sqengine.VAR_SQTWITTER_NOTIFY_REPLIES), out notify);

            if (notify)
            {
                if (_reply_messagecount != -1)
                {

                    if (_reply_list.Count > _reply_messagecount)
                    {
                        string from = _reply_list[0].TwitterUser.ScreenName;
                        string mesg = _reply_list[0].Text;

                        if (((sqengine)_game).IsConsoleActive)
                        {
                            (((sqengine)_game)).Console.AddConsole(string.Format("$4[Twitter]: Reply $0{0}: {1}", from, mesg));
                        }
                        else
                        {
                            (((sqengine)_game)).AddMessage(string.Format("Reply from Twitter\n{0}: {1}", from, mesg), Color.Red, 4000, "Textures/UI/twitter-logo");
                        }

                        _reply_messagecount = _reply_list.Count;

                    }
                }
                else
                {

                    _reply_messagecount = _reply_list.Count;
                }

            }
        }






    }
}
